package hyl.base.net.bio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import hyl.base.net.IpgReader;
import hyl.base.net.ISocketSrv;
import hyl.core.MyFun;
import hyl.core.net.MySocket;
import hyl.core.run.IDo1;
import hyl.core.run.MyRun;

//这个对象 即可以作为服务端也可以作为客户端
public class BIOSocketSrv extends BIOSocket implements ISocketSrv {

	// 服务器对象，用于监听TCP端口
	ServerSocket _server;
	// socket
	List<IpgReader> socketList = new ArrayList<>();
	int i线程数 = 0;

	/**
	 * 默认只开启两个服务,只允许连接两个终端
	 * 
	 * @param port
	 */
	public BIOSocketSrv(int port) {
		this(port, 2);
	}

	/**
	 * 实例化服务端<br>
	 * 这是专门为了 小集群系统(小于256个微服务程序) 设计的 微服务底层通信组件<br>
	 * 特别注意这不是nio 模式,每个线程针对一个客户端,保持长连接<br>
	 * , 超过128线程 ,将无法接入客户端<br>
	 * 如果需要大量的客户端绑定,我们设计了NIOsocket 组件 <br>
	 * 
	 * 大量的对象 需要非常大的内存,如何优化是关键
	 * 
	 * 构造函数，必须输入端口号
	 * 
	 * @param port   服务端口
	 * @param 接收处理函数 一个socket 一个处理函数与线程对应
	 * 
	 * 
	 * 
	 */
	public BIOSocketSrv(int port, int 线程数) {
		i线程数 = 线程数;
		_work = MyRun.getInstance("网络服", 线程数);
		try {
			// 绑定端口
			this._server = new ServerSocket(port);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public BIOSocketSrv(int port, IDo1<IpgReader> 接收处理函数) {

		this(port, 2);
		_IDo接收处理函数 = 接收处理函数;
	}

	public BIOSocketSrv(int port, int 线程数, IDo1<IpgReader> 接收处理函数) {

		this(port, 线程数);
		_IDo接收处理函数 = 接收处理函数;
	}

	/**
	 * 启动服务器 如果有客户端接入就开一个服务线程，
	 * 
	 */
	public void startServer() {
		if (_IDo接收处理函数 == null)
			return;
		Socket socket = null;
		try {

			while (true) {
				if (b是否退出程序)
					break;
				socket = _server.accept();
				String stt = MyFun.join("客户端接入:", socket.getInetAddress(), ":", socket.getPort());
				_log.info(stt);
				BIOReader read = new BIOReader(this, socket, _IDo接收处理函数);
				socketList.add(read);
				_work.execute(read);

			}
		} catch (IOException e) {
			_log.error(e.getMessage());
			e.printStackTrace();
		}
	}

	@Override
	public void close() {
		_work.close();
		b是否退出程序 = true;
		socketList.clear();
		try {
			_server.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("null")
	/**
	 * 发送个接收人群
	 * 
	 * @param 类型
	 * @param 数据包
	 * @param 接收人群
	 * @return
	 */
	public static int sendMany(byte 类型, byte[] 数据包, List<Socket> 接收人群) {
		if (数据包 != null || 接收人群 != null)
			return 0;
		int i = 0;
		try {
			BIOData1 dp = new BIOData1();
			dp.data = 数据包;
			dp.i类型 = 类型;

			byte[] data = dp.getSendBytes();
			for (Socket so : 接收人群) {
				try {
					MySocket.sendBytes(so, data);
					i++;
				} catch (Exception e) {

				}
			}
			return i;
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	/**
	 * 发送给连接服务端口的所有人
	 * 
	 * @param 数据包
	 * @throws IOException
	 */
	public int sendAll(byte 类型, byte[] 数据包) {
		return sendEx(null, 类型, 数据包);
	}

	/**
	 * 发送除开他的其他所有人
	 * 
	 * @param 数据包
	 * @throws IOException
	 */
	public int sendEx(IpgReader 排除他, byte 类型, byte[] 数据包) {
		if (数据包 != null && !socketList.isEmpty())
			return 0;
		int i = 0;
		try {
			BIOData1 dp = new BIOData1();
			dp.data = 数据包;
			dp.i类型 = 类型;

			byte[] data = dp.getSendBytes();

			for (IpgReader rd : socketList) {
				if (rd == 排除他)
					continue;

				if (rd.send(data))
					i++;
			}

		} catch (Exception e) {
			e.printStackTrace();

		}
		return i;
	}

}
